#include "../multicaster.h"
#include "../event_handler.h"
#include "../../network/xml_filetype.h"
#include "../../network/i_socket.h"
#include "../../network/connection_manager.h"

#include <boost/weak_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <iostream>
#include <unistd.h>

using namespace std;

class my_handler : public handler::event_handler {
public:
	my_handler(boost::shared_ptr<network::i_socket> sock)
	: _socket(sock)
	{
	}

	static boost::shared_ptr<my_handler> create(
		boost::shared_ptr<network::i_socket> s)
	{
		boost::shared_ptr<my_handler> h(new my_handler(s));
		h->_this = h;
		return h;
	}

	virtual void handle_event(boost::shared_ptr<network::message> msg)
	{
		switch(msg->type) {
		case network::RECEIVE:
			cout << "receive" << endl;
			cout << msg->node->to_string() << endl;
			break;
		case network::CONNECT:
			cout << "connect" << endl;
			break;
		case network::DELETE:
			cout << "delete" << endl;
			boost::shared_ptr<my_handler> h(_this.lock());
			fire_listener();
			h.reset();
			break;
		}
	}

private:
	boost::shared_ptr<network::i_socket> _socket;
	boost::weak_ptr<my_handler> _this;
};

class my_acceptor : public handler::event_handler {
public:
	my_acceptor(boost::shared_ptr<handler::multicaster> multi, 
			boost::shared_ptr<network::connection_manager> mgr)
	: _multi(multi), _con_mgr(mgr)
	{
	}

	virtual void handle_event(boost::shared_ptr<network::message> msg)
	{
		switch(msg->type) {
		case network::RECEIVE:
			cout << "receive" << endl;
			break;
		case network::CONNECT:
		{
			cout << "creating receiver..." << endl;
			boost::shared_ptr<my_handler> h(my_handler::create(msg->new_sock));
			_multi->add_handler(network::RECEIVE, msg->new_sock, h);
			_multi->add_handler(network::DELETE, msg->new_sock, h);
			_con_mgr->add_recv(msg->new_sock, 
				boost::shared_ptr<network::xml_filetype>(
					new network::xml_filetype()));
			break;
		}
		case network::DELETE:
			cout << "delete" << endl;
			break;
		}
	}
private:
	boost::shared_ptr<handler::multicaster> _multi;
	boost::shared_ptr<network::connection_manager> _con_mgr;
};


int main(int argc, char *argv[])
{
	boost::shared_ptr<network::message_queue> q(new network::message_queue);
	boost::shared_ptr<network::connection_manager> mgr(new 
		network::connection_manager(q));
	boost::shared_ptr<handler::multicaster> multi(
		handler::multicaster::create(q));

	boost::shared_ptr<network::i_socket> server_sock(
		mgr->add_listener(123456));

	boost::shared_ptr<my_acceptor> acc(new my_acceptor(multi, mgr));
	multi->add_handler(network::CONNECT, server_sock, acc);

	while(true) {
		usleep(1000);
	}
	
	return 0;
}

